import { observe } from '../observer/index.js'

export function initState(vm) {
  const options = vm.$options
  let data = options.data
  // 先看是不是函数，如果是函数，就要调用才能拿到 data 对象
  if (typeof data === 'function') {
    // data = data() // 这个指向全局对象 window
    data = data.call(vm) // 在调用同时把 data 函数内部的 this 指向改成当前 vue 实例
  }

  vm._data = data

  // 数据代理到 vue 实例上
  proxy(vm)

  // 将 data 转换成可观察对象
  observe(vm._data)
}

// 将 data 代理到 vm 实例身上
function proxy(vm) {
  const data = vm._data

  for (const k of Object.keys(data)) {
    Object.defineProperty(vm, k, {
      get() {
        console.log('[Vue实例数据代理] => 在访问 vm 实例身上的', k)
        // k ==> 'count'
        // 在访问 vm[k] ==> vm['count'] ==> 会进入这个 get 函数 ==> 值：data['count']
        return data[k]
      },
      set(newValue) {
        console.log(
          '[Vue实例数据代理] => 在设置 vm 实例身上的',
          k,
          '，值为：',
          newValue
        )
        // k ==> 'count'
        // vm[k] ==> vm['count'] ==> vm.count ==> 赋值就会触发 set 函数 ==> data[k] = newValue ==> data.count = newValue ==> 触发 data 的 count 属性的 set
        data[k] = newValue
      },
    })
  }
}
